home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / Kubuntu 8.10 / kubuntu-8.10-desktop-i386.iso / casper / filesystem.squashfs / usr / lib / ruby / 1.8 / optparse.rb < prev    next >
Text File  |  2008-07-17  |  48KB  |  1,792 lines

  1. #
  2. # optparse.rb - command-line option analysis with the OptionParser class.
  3. # Author:: Nobu Nakada
  4. # Documentation:: Nobu Nakada and Gavin Sinclair.
  5. #
  6. # See OptionParser for documentation. 
  7. #
  8.  
  9.  
  10. # == Developer Documentation (not for RDoc output) 
  11. # === Class tree
  12. #
  13. # - OptionParser:: front end
  14. # - OptionParser::Switch:: each switches
  15. # - OptionParser::List:: options list
  16. # - OptionParser::ParseError:: errors on parsing
  17. #   - OptionParser::AmbiguousOption
  18. #   - OptionParser::NeedlessArgument
  19. #   - OptionParser::MissingArgument
  20. #   - OptionParser::InvalidOption
  21. #   - OptionParser::InvalidArgument
  22. #     - OptionParser::AmbiguousArgument
  23. #
  24. # === Object relationship diagram
  25. #
  26. #   +--------------+
  27. #   | OptionParser |<>-----+
  28. #   +--------------+       |                      +--------+
  29. #                          |                    ,-| Switch |
  30. #        on_head -------->+---------------+    /  +--------+
  31. #        accept/reject -->| List          |<|>-
  32. #                         |               |<|>-  +----------+
  33. #        on ------------->+---------------+    `-| argument |
  34. #                           :           :        |  class   |
  35. #                         +---------------+      |==========|
  36. #        on_tail -------->|               |      |pattern   |
  37. #                         +---------------+      |----------|
  38. #   OptionParser.accept ->| DefaultList   |      |converter |
  39. #                reject   |(shared between|      +----------+
  40. #                         | all instances)|
  41. #                         +---------------+
  42. #
  43. # == OptionParser
  44. #
  45. # === Introduction
  46. #
  47. # OptionParser is a class for command-line option analysis.  It is much more
  48. # advanced, yet also easier to use, than GetoptLong, and is a more Ruby-oriented
  49. # solution.
  50. #
  51. # === Features
  52. # 1. The argument specification and the code to handle it are written in the
  53. #    same place.
  54. # 2. It can output an option summary; you don't need to maintain this string
  55. #    separately.
  56. # 3. Optional and mandatory arguments are specified very gracefully.
  57. # 4. Arguments can be automatically converted to a specified class.
  58. # 5. Arguments can be restricted to a certain set.
  59. #
  60. # All of these features are demonstrated in the examples below.
  61. #
  62. # === Minimal example
  63. #
  64. #   require 'optparse'
  65. #
  66. #   options = {}
  67. #   OptionParser.new do |opts|
  68. #     opts.banner = "Usage: example.rb [options]"
  69. #
  70. #     opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
  71. #       options[:verbose] = v
  72. #     end
  73. #   end.parse!
  74. #
  75. #   p options
  76. #   p ARGV
  77. #
  78. # === Complete example
  79. #
  80. # The following example is a complete Ruby program.  You can run it and see the
  81. # effect of specifying various options.  This is probably the best way to learn
  82. # the features of +optparse+.
  83. #
  84. #   require 'optparse'
  85. #   require 'optparse/time'
  86. #   require 'ostruct'
  87. #   require 'pp'
  88. #   
  89. #   class OptparseExample
  90. #   
  91. #     CODES = %w[iso-2022-jp shift_jis euc-jp utf8 binary]
  92. #     CODE_ALIASES = { "jis" => "iso-2022-jp", "sjis" => "shift_jis" }
  93. #   
  94. #     #
  95. #     # Return a structure describing the options.
  96. #     #
  97. #     def self.parse(args)
  98. #       # The options specified on the command line will be collected in *options*.
  99. #       # We set default values here.
  100. #       options = OpenStruct.new
  101. #       options.library = []
  102. #       options.inplace = false
  103. #       options.encoding = "utf8"
  104. #       options.transfer_type = :auto
  105. #       options.verbose = false
  106. #       
  107. #       opts = OptionParser.new do |opts|
  108. #         opts.banner = "Usage: example.rb [options]"
  109. #       
  110. #         opts.separator ""
  111. #         opts.separator "Specific options:"
  112. #       
  113. #         # Mandatory argument.
  114. #         opts.on("-r", "--require LIBRARY",
  115. #                 "Require the LIBRARY before executing your script") do |lib|
  116. #           options.library << lib
  117. #         end
  118. #       
  119. #         # Optional argument; multi-line description.
  120. #         opts.on("-i", "--inplace [EXTENSION]",
  121. #                 "Edit ARGV files in place",
  122. #                 "  (make backup if EXTENSION supplied)") do |ext|
  123. #           options.inplace = true
  124. #           options.extension = ext || ''
  125. #           options.extension.sub!(/\A\.?(?=.)/, ".")  # Ensure extension begins with dot.
  126. #         end
  127. #       
  128. #         # Cast 'delay' argument to a Float.
  129. #         opts.on("--delay N", Float, "Delay N seconds before executing") do |n|
  130. #           options.delay = n
  131. #         end
  132. #       
  133. #         # Cast 'time' argument to a Time object.
  134. #         opts.on("-t", "--time [TIME]", Time, "Begin execution at given time") do |time|
  135. #           options.time = time
  136. #         end
  137. #       
  138. #         # Cast to octal integer.
  139. #         opts.on("-F", "--irs [OCTAL]", OptionParser::OctalInteger,
  140. #                 "Specify record separator (default \\0)") do |rs|
  141. #           options.record_separator = rs
  142. #         end
  143. #       
  144. #         # List of arguments.
  145. #         opts.on("--list x,y,z", Array, "Example 'list' of arguments") do |list|
  146. #           options.list = list
  147. #         end
  148. #       
  149. #         # Keyword completion.  We are specifying a specific set of arguments (CODES
  150. #         # and CODE_ALIASES - notice the latter is a Hash), and the user may provide
  151. #         # the shortest unambiguous text.
  152. #         code_list = (CODE_ALIASES.keys + CODES).join(',')
  153. #         opts.on("--code CODE", CODES, CODE_ALIASES, "Select encoding",
  154. #                 "  (#{code_list})") do |encoding|
  155. #           options.encoding = encoding
  156. #         end
  157. #       
  158. #         # Optional argument with keyword completion.
  159. #         opts.on("--type [TYPE]", [:text, :binary, :auto],
  160. #                 "Select transfer type (text, binary, auto)") do |t|
  161. #           options.transfer_type = t
  162. #         end
  163. #       
  164. #         # Boolean switch.
  165. #         opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
  166. #           options.verbose = v
  167. #         end
  168. #       
  169. #         opts.separator ""
  170. #         opts.separator "Common options:"
  171. #       
  172. #         # No argument, shows at tail.  This will print an options summary.
  173. #         # Try it and see!
  174. #         opts.on_tail("-h", "--help", "Show this message") do
  175. #           puts opts
  176. #           exit
  177. #         end
  178. #       
  179. #         # Another typical switch to print the version.
  180. #         opts.on_tail("--version", "Show version") do
  181. #           puts OptionParser::Version.join('.')
  182. #           exit
  183. #         end
  184. #       end
  185. #       
  186. #       opts.parse!(args)
  187. #       options
  188. #     end  # parse()
  189. #   
  190. #   end  # class OptparseExample
  191. #   
  192. #   options = OptparseExample.parse(ARGV)
  193. #   pp options
  194. #
  195. # === Further documentation
  196. #
  197. # The above examples should be enough to learn how to use this class.  If you
  198. # have any questions, email me (gsinclair@soyabean.com.au) and I will update
  199. # this document.
  200. #
  201. class OptionParser
  202.   # :stopdoc:
  203.   RCSID = %w$Id: optparse.rb 18110 2008-07-17 12:31:06Z shyouhei $[1..-1].each {|s| s.freeze}.freeze
  204.   Version = (RCSID[1].split('.').collect {|s| s.to_i}.extend(Comparable).freeze if RCSID[1])
  205.   LastModified = (Time.gm(*RCSID[2, 2].join('-').scan(/\d+/).collect {|s| s.to_i}) if RCSID[2])
  206.   Release = RCSID[2]
  207.  
  208.   NoArgument = [NO_ARGUMENT = :NONE, nil].freeze
  209.   RequiredArgument = [REQUIRED_ARGUMENT = :REQUIRED, true].freeze
  210.   OptionalArgument = [OPTIONAL_ARGUMENT = :OPTIONAL, false].freeze
  211.   # :startdoc:
  212.  
  213.   #
  214.   # Keyword completion module.  This allows partial arguments to be specified
  215.   # and resolved against a list of acceptable values.
  216.   #
  217.   module Completion
  218.     def complete(key, icase = false, pat = nil)
  219.       pat ||= Regexp.new('\A' + Regexp.quote(key).gsub(/\w+\b/, '\&\w*'),
  220.                          icase)
  221.       canon, sw, k, v, cn = nil
  222.       candidates = []
  223.       each do |k, *v|
  224.         (if Regexp === k
  225.            kn = nil
  226.            k === key
  227.          else
  228.            kn = defined?(k.id2name) ? k.id2name : k
  229.            pat === kn
  230.          end) or next
  231.         v << k if v.empty?
  232.         candidates << [k, v, kn]
  233.       end
  234.       candidates = candidates.sort_by {|k, v, kn| kn.size}
  235.       if candidates.size == 1
  236.         canon, sw, * = candidates[0]
  237.       elsif candidates.size > 1
  238.         canon, sw, cn = candidates.shift
  239.         candidates.each do |k, v, kn|
  240.           next if sw == v
  241.           if String === cn and String === kn
  242.             if cn.rindex(kn, 0)
  243.               canon, sw, cn = k, v, kn
  244.               next
  245.             elsif kn.rindex(cn, 0)
  246.               next
  247.             end
  248.           end
  249.           throw :ambiguous, key
  250.         end
  251.       end
  252.       if canon
  253.         block_given? or return key, *sw
  254.         yield(key, *sw)
  255.       end
  256.     end
  257.  
  258.     def convert(opt = nil, val = nil, *)
  259.       val
  260.     end
  261.   end
  262.  
  263.  
  264.   #
  265.   # Map from option/keyword string to object with completion.
  266.   #
  267.   class OptionMap < Hash
  268.     include Completion
  269.   end
  270.  
  271.  
  272.   #
  273.   # Individual switch class.  Not important to the user.
  274.   #
  275.   # Defined within Switch are several Switch-derived classes: NoArgument,
  276.   # RequiredArgument, etc. 
  277.   #
  278.   class Switch
  279.     attr_reader :pattern, :conv, :short, :long, :arg, :desc, :block
  280.  
  281.     #
  282.     # Guesses argument style from +arg+.  Returns corresponding
  283.     # OptionParser::Switch class (OptionalArgument, etc.).
  284.     #
  285.     def self.guess(arg)
  286.       case arg
  287.       when ""
  288.         t = self
  289.       when /\A=?\[/
  290.         t = Switch::OptionalArgument
  291.       when /\A\s+\[/
  292.         t = Switch::PlacedArgument
  293.       else
  294.         t = Switch::RequiredArgument
  295.       end
  296.       self >= t or incompatible_argument_styles(arg, t)
  297.       t
  298.     end
  299.  
  300.     def self.incompatible_argument_styles(arg, t)
  301.       raise ArgumentError, "#{arg}: incompatible argument styles\n  #{self}, #{t}"
  302.     end
  303.  
  304.     def self.pattern
  305.       NilClass
  306.     end
  307.  
  308.     def initialize(pattern = nil, conv = nil,
  309.                    short = nil, long = nil, arg = nil,
  310.                    desc = ([] if short or long), block = Proc.new)
  311.       raise if Array === pattern
  312.       @pattern, @conv, @short, @long, @arg, @desc, @block =
  313.         pattern, conv, short, long, arg, desc, block
  314.     end
  315.  
  316.     #
  317.     # Parses +arg+ and returns rest of +arg+ and matched portion to the
  318.     # argument pattern. Yields when the pattern doesn't match substring.
  319.     #
  320.     def parse_arg(arg)
  321.       pattern or return nil, arg
  322.       unless m = pattern.match(arg)
  323.         yield(InvalidArgument, arg)
  324.         return arg, nil
  325.       end
  326.       if String === m
  327.         m = [s = m]
  328.       else
  329.         m = m.to_a
  330.         s = m[0]
  331.         return nil, m unless String === s
  332.       end
  333.       raise InvalidArgument, arg unless arg.rindex(s, 0)
  334.       return nil, m if s.length == arg.length
  335.       yield(InvalidArgument, arg) # didn't match whole arg
  336.       return arg[s.length..-1], m
  337.     end
  338.     private :parse_arg
  339.  
  340.     #
  341.     # Parses argument, converts and returns +arg+, +block+ and result of
  342.     # conversion. Yields at semi-error condition instead of raising an
  343.     # exception.
  344.     #
  345.     def conv_arg(arg, val = nil)
  346.       if conv
  347.         val = conv.call(*val)
  348.       else
  349.         val = proc {|val| val}.call(*val)
  350.       end
  351.       return arg, block, val
  352.     end
  353.     private :conv_arg
  354.  
  355.     #
  356.     # Produces the summary text. Each line of the summary is yielded to the
  357.     # block (without newline).
  358.     #
  359.     # +sdone+::  Already summarized short style options keyed hash.
  360.     # +ldone+::  Already summarized long style options keyed hash.
  361.     # +width+::  Width of left side (option part). In other words, the right
  362.     #            side (description part) starts after +width+ columns.
  363.     # +max+::    Maximum width of left side -> the options are filled within
  364.     #            +max+ columns.
  365.     # +indent+:: Prefix string indents all summarized lines.
  366.     #
  367.     def summarize(sdone = [], ldone = [], width = 1, max = width - 1, indent = "")
  368.       sopts, lopts, s = [], [], nil
  369.       @short.each {|s| sdone.fetch(s) {sopts << s}; sdone[s] = true} if @short
  370.       @long.each {|s| ldone.fetch(s) {lopts << s}; ldone[s] = true} if @long
  371.       return if sopts.empty? and lopts.empty? # completely hidden
  372.  
  373.       left = [sopts.join(', ')]
  374.       right = desc.dup
  375.  
  376.       while s = lopts.shift
  377.         l = left[-1].length + s.length
  378.         l += arg.length if left.size == 1 && arg
  379.         l < max or sopts.empty? or left << ''
  380.         left[-1] << if left[-1].empty? then ' ' * 4 else ', ' end << s
  381.       end
  382.  
  383.       left[0] << arg if arg
  384.       mlen = left.collect {|s| s.length}.max.to_i
  385.       while mlen > width and l = left.shift
  386.         mlen = left.collect {|s| s.length}.max.to_i if l.length == mlen
  387.         yield(indent + l)
  388.       end
  389.  
  390.       while begin l = left.shift; r = right.shift; l or r end
  391.         l = l.to_s.ljust(width) + ' ' + r if r and !r.empty?
  392.         yield(indent + l)
  393.       end
  394.  
  395.       self
  396.     end
  397.  
  398.     def add_banner(to)  # :nodoc:
  399.       unless @short or @long
  400.         s = desc.join
  401.         to << " [" + s + "]..." unless s.empty?
  402.       end
  403.       to
  404.     end
  405.  
  406.     def match_nonswitch?(str) # :nodoc:
  407.       @pattern =~ str unless @short or @long
  408.     end
  409.  
  410.     #
  411.     # Main name of the switch.
  412.     #
  413.     def switch_name
  414.       (long.first || short.first).sub(/\A-+(?:\[no-\])?/, '')
  415.     end
  416.  
  417.     #
  418.     # Switch that takes no arguments.
  419.     #
  420.     class NoArgument < self
  421.  
  422.       #
  423.       # Raises an exception if any arguments given.
  424.       #
  425.       def parse(arg, argv)
  426.         yield(NeedlessArgument, arg) if arg
  427.         conv_arg(arg)
  428.       end
  429.  
  430.       def self.incompatible_argument_styles(*)
  431.       end
  432.  
  433.       def self.pattern
  434.         Object
  435.       end
  436.     end
  437.  
  438.     #
  439.     # Switch that takes an argument.
  440.     #
  441.     class RequiredArgument < self
  442.  
  443.       #
  444.       # Raises an exception if argument is not present.
  445.       #
  446.       def parse(arg, argv)
  447.         unless arg
  448.           raise MissingArgument if argv.empty?
  449.           arg = argv.shift
  450.         end
  451.         conv_arg(*parse_arg(arg) {|*exc| raise(*exc)})
  452.       end
  453.     end
  454.  
  455.     #
  456.     # Switch that can omit argument.
  457.     #
  458.     class OptionalArgument < self
  459.  
  460.       #
  461.       # Parses argument if given, or uses default value.
  462.       #
  463.       def parse(arg, argv, &error)
  464.         if arg
  465.           conv_arg(*parse_arg(arg, &error))
  466.         else
  467.           conv_arg(arg)
  468.         end
  469.       end
  470.     end
  471.  
  472.     #
  473.     # Switch that takes an argument, which does not begin with '-'.
  474.     #
  475.     class PlacedArgument < self
  476.  
  477.       #
  478.       # Returns nil if argument is not present or begins with '-'.
  479.       #
  480.       def parse(arg, argv, &error)
  481.         if !(val = arg) and (argv.empty? or /\A-/ =~ (val = argv[0]))
  482.           return nil, block, nil
  483.         end
  484.         opt = (val = parse_arg(val, &error))[1]
  485.         val = conv_arg(*val)
  486.         if opt and !arg
  487.           argv.shift
  488.         else
  489.           val[0] = nil
  490.         end
  491.         val
  492.       end
  493.     end
  494.   end
  495.  
  496.   #
  497.   # Simple option list providing mapping from short and/or long option
  498.   # string to OptionParser::Switch and mapping from acceptable argument to
  499.   # matching pattern and converter pair. Also provides summary feature.
  500.   #
  501.   class List
  502.     # Map from acceptable argument types to pattern and converter pairs.
  503.     attr_reader :atype
  504.     
  505.     # Map from short style option switches to actual switch objects.
  506.     attr_reader :short
  507.     
  508.     # Map from long style option switches to actual switch objects.
  509.     attr_reader :long
  510.     
  511.     # List of all switches and summary string.
  512.     attr_reader :list
  513.  
  514.     #
  515.     # Just initializes all instance variables.
  516.     #
  517.     def initialize
  518.       @atype = {}
  519.       @short = OptionMap.new
  520.       @long = OptionMap.new
  521.       @list = []
  522.     end
  523.  
  524.     #
  525.     # See OptionParser.accept.
  526.     #
  527.     def accept(t, pat = /.*/nm, &block)
  528.       if pat
  529.         pat.respond_to?(:match) or raise TypeError, "has no `match'"
  530.       else
  531.         pat = t if t.respond_to?(:match)
  532.       end
  533.       unless block
  534.         block = pat.method(:convert).to_proc if pat.respond_to?(:convert)
  535.       end
  536.       @atype[t] = [pat, block]
  537.     end
  538.  
  539.     #
  540.     # See OptionParser.reject.
  541.     #
  542.     def reject(t)
  543.       @atype.delete(t)
  544.     end
  545.  
  546.     #
  547.     # Adds +sw+ according to +sopts+, +lopts+ and +nlopts+.
  548.     #
  549.     # +sw+::     OptionParser::Switch instance to be added.
  550.     # +sopts+::  Short style option list.
  551.     # +lopts+::  Long style option list.
  552.     # +nlopts+:: Negated long style options list.
  553.     #
  554.     def update(sw, sopts, lopts, nsw = nil, nlopts = nil)
  555.       o = nil
  556.       sopts.each {|o| @short[o] = sw} if sopts
  557.       lopts.each {|o| @long[o] = sw} if lopts
  558.       nlopts.each {|o| @long[o] = nsw} if nsw and nlopts
  559.       used = @short.invert.update(@long.invert)
  560.       @list.delete_if {|o| Switch === o and !used[o]}
  561.     end
  562.     private :update
  563.  
  564.     #
  565.     # Inserts +switch+ at the head of the list, and associates short, long
  566.     # and negated long options. Arguments are:
  567.     # 
  568.     # +switch+::      OptionParser::Switch instance to be inserted.
  569.     # +short_opts+::  List of short style options.
  570.     # +long_opts+::   List of long style options.
  571.     # +nolong_opts+:: List of long style options with "no-" prefix.
  572.     #
  573.     #   prepend(switch, short_opts, long_opts, nolong_opts)
  574.     #
  575.     def prepend(*args)
  576.       update(*args)
  577.       @list.unshift(args[0])
  578.     end
  579.  
  580.     #
  581.     # Appends +switch+ at the tail of the list, and associates short, long
  582.     # and negated long options. Arguments are:
  583.     # 
  584.     # +switch+::      OptionParser::Switch instance to be inserted.
  585.     # +short_opts+::  List of short style options.
  586.     # +long_opts+::   List of long style options.
  587.     # +nolong_opts+:: List of long style options with "no-" prefix.
  588.     #
  589.     #   append(switch, short_opts, long_opts, nolong_opts)
  590.     #
  591.     def append(*args)
  592.       update(*args)
  593.       @list.push(args[0])
  594.     end
  595.  
  596.     #
  597.     # Searches +key+ in +id+ list. The result is returned or yielded if a
  598.     # block is given. If it isn't found, nil is returned.
  599.     #
  600.     def search(id, key)
  601.       if list = __send__(id)
  602.         val = list.fetch(key) {return nil}
  603.         block_given? ? yield(val) : val
  604.       end
  605.     end
  606.  
  607.     #
  608.     # Searches list +id+ for +opt+ and the optional patterns for completion
  609.     # +pat+. If +icase+ is true, the search is case insensitive. The result
  610.     # is returned or yielded if a block is given. If it isn't found, nil is
  611.     # returned.
  612.     #
  613.     def complete(id, opt, icase = false, *pat, &block)
  614.       __send__(id).complete(opt, icase, *pat, &block)
  615.     end
  616.  
  617.     #
  618.     # Iterates over each option, passing the option to the +block+.
  619.     #
  620.     def each_option(&block)
  621.       list.each(&block)
  622.     end
  623.  
  624.     #
  625.     # Creates the summary table, passing each line to the +block+ (without
  626.     # newline). The arguments +args+ are passed along to the summarize
  627.     # method which is called on every option.
  628.     #
  629.     def summarize(*args, &block)
  630.       list.each do |opt|
  631.         if opt.respond_to?(:summarize) # perhaps OptionParser::Switch
  632.           opt.summarize(*args, &block)
  633.         elsif !opt
  634.           yield("")
  635.         elsif opt.respond_to?(:each_line)
  636.           opt.each_line(&block)
  637.         else
  638.           opt.each(&block)
  639.         end
  640.       end
  641.     end
  642.  
  643.     def add_banner(to)  # :nodoc:
  644.       list.each do |opt|
  645.         if opt.respond_to?(:add_banner)
  646.           opt.add_banner(to)
  647.         end
  648.       end
  649.       to
  650.     end
  651.   end
  652.  
  653.   #
  654.   # Hash with completion search feature. See OptionParser::Completion.
  655.   #
  656.   class CompletingHash < Hash
  657.     include Completion
  658.  
  659.     #
  660.     # Completion for hash key.
  661.     #
  662.     def match(key)
  663.       return key, *fetch(key) {
  664.         raise AmbiguousArgument, catch(:ambiguous) {return complete(key)}
  665.       }
  666.     end
  667.   end
  668.  
  669.   # :stopdoc:
  670.  
  671.   #
  672.   # Enumeration of acceptable argument styles. Possible values are:
  673.   #
  674.   # NO_ARGUMENT::       The switch takes no arguments. (:NONE)
  675.   # REQUIRED_ARGUMENT:: The switch requires an argument. (:REQUIRED)
  676.   # OPTIONAL_ARGUMENT:: The switch requires an optional argument. (:OPTIONAL)
  677.   #
  678.   # Use like --switch=argument (long style) or -Xargument (short style). For
  679.   # short style, only portion matched to argument pattern is dealed as
  680.   # argument.
  681.   #
  682.   ArgumentStyle = {}
  683.   NoArgument.each {|el| ArgumentStyle[el] = Switch::NoArgument}
  684.   RequiredArgument.each {|el| ArgumentStyle[el] = Switch::RequiredArgument}
  685.   OptionalArgument.each {|el| ArgumentStyle[el] = Switch::OptionalArgument}
  686.   ArgumentStyle.freeze
  687.  
  688.   #
  689.   # Switches common used such as '--', and also provides default
  690.   # argument classes
  691.   #
  692.   DefaultList = List.new
  693.   DefaultList.short['-'] = Switch::NoArgument.new {}
  694.   DefaultList.long[''] = Switch::NoArgument.new {throw :terminate}
  695.  
  696.   #
  697.   # Default options for ARGV, which never appear in option summary.
  698.   #
  699.   Officious = {}
  700.  
  701.   #
  702.   # --help
  703.   # Shows option summary.
  704.   #
  705.   Officious['help'] = proc do |parser|
  706.     Switch::NoArgument.new do
  707.       puts parser.help
  708.       exit
  709.     end
  710.   end
  711.  
  712.   #
  713.   # --version
  714.   # Shows version string if Version is defined.
  715.   #
  716.   Officious['version'] = proc do |parser|
  717.     Switch::OptionalArgument.new do |pkg|
  718.       if pkg
  719.         begin
  720.           require 'optparse/version'
  721.         rescue LoadError
  722.         else
  723.           show_version(*pkg.split(/,/)) or
  724.             abort("#{parser.program_name}: no version found in package #{pkg}")
  725.           exit
  726.         end
  727.       end
  728.       v = parser.ver or abort("#{parser.program_name}: version unknown")
  729.       puts v
  730.       exit
  731.     end
  732.   end
  733.  
  734.   # :startdoc:
  735.  
  736.   #
  737.   # Class methods
  738.   #
  739.  
  740.   #
  741.   # Initializes a new instance and evaluates the optional block in context
  742.   # of the instance. Arguments +args+ are passed to #new, see there for
  743.   # description of parameters.
  744.   # 
  745.   # This method is *deprecated*, its behavior corresponds to the older #new
  746.   # method.
  747.   #
  748.   def self.with(*args, &block)
  749.     opts = new(*args)
  750.     opts.instance_eval(&block)
  751.     opts
  752.   end
  753.  
  754.   #
  755.   # Returns an incremented value of +default+ according to +arg+.
  756.   #
  757.   def self.inc(arg, default = nil)
  758.     case arg
  759.     when Integer
  760.       arg.nonzero?
  761.     when nil
  762.       default.to_i + 1
  763.     end
  764.   end
  765.   def inc(*args)
  766.     self.class.inc(*args)
  767.   end
  768.  
  769.   #
  770.   # Initializes the instance and yields itself if called with a block.
  771.   #
  772.   # +banner+:: Banner message.
  773.   # +width+::  Summary width.
  774.   # +indent+:: Summary indent.
  775.   #
  776.   def initialize(banner = nil, width = 32, indent = ' ' * 4)
  777.     @stack = [DefaultList, List.new, List.new]
  778.     @program_name = nil
  779.     @banner = banner
  780.     @summary_width = width
  781.     @summary_indent = indent
  782.     @default_argv = ARGV
  783.     add_officious
  784.     yield self if block_given?
  785.   end
  786.  
  787.   def add_officious  # :nodoc:
  788.     list = base()
  789.     Officious.each do |opt, block|
  790.       list.long[opt] ||= block.call(self)
  791.     end
  792.   end
  793.  
  794.   #
  795.   # Terminates option parsing. Optional parameter +arg+ is a string pushed
  796.   # back to be the first non-option argument.
  797.   #
  798.   def terminate(arg = nil)
  799.     self.class.terminate(arg)
  800.   end
  801.   def self.terminate(arg = nil)
  802.     throw :terminate, arg
  803.   end
  804.  
  805.   @stack = [DefaultList]
  806.   def self.top() DefaultList end
  807.  
  808.   #
  809.   # Directs to accept specified class +t+. The argument string is passed to
  810.   # the block in which it should be converted to the desired class.
  811.   #
  812.   # +t+::   Argument class specifier, any object including Class.
  813.   # +pat+:: Pattern for argument, defaults to +t+ if it responds to match.
  814.   #
  815.   #   accept(t, pat, &block)
  816.   #
  817.   def accept(*args, &blk) top.accept(*args, &blk) end
  818.   #
  819.   # See #accept.
  820.   #
  821.   def self.accept(*args, &blk) top.accept(*args, &blk) end
  822.  
  823.   #
  824.   # Directs to reject specified class argument.
  825.   #
  826.   # +t+:: Argument class specifier, any object including Class.
  827.   #
  828.   #   reject(t)
  829.   #
  830.   def reject(*args, &blk) top.reject(*args, &blk) end
  831.   #
  832.   # See #reject.
  833.   #
  834.   def self.reject(*args, &blk) top.reject(*args, &blk) end
  835.  
  836.   #
  837.   # Instance methods
  838.   #
  839.  
  840.   # Heading banner preceding summary.
  841.   attr_writer :banner
  842.  
  843.   # Program name to be emitted in error message and default banner,
  844.   # defaults to $0.
  845.   attr_writer :program_name
  846.  
  847.   # Width for option list portion of summary. Must be Numeric.
  848.   attr_accessor :summary_width
  849.  
  850.   # Indentation for summary. Must be String (or have + String method).
  851.   attr_accessor :summary_indent
  852.  
  853.   # Strings to be parsed in default.
  854.   attr_accessor :default_argv
  855.  
  856.   #
  857.   # Heading banner preceding summary.
  858.   #
  859.   def banner
  860.     unless @banner
  861.       @banner = "Usage: #{program_name} [options]"
  862.       visit(:add_banner, @banner)
  863.     end
  864.     @banner
  865.   end
  866.  
  867.   #
  868.   # Program name to be emitted in error message and default banner, defaults
  869.   # to $0.
  870.   #
  871.   def program_name
  872.     @program_name || File.basename($0, '.*')
  873.   end
  874.  
  875.   # for experimental cascading :-)
  876.   alias set_banner banner=
  877.   alias set_program_name program_name=
  878.   alias set_summary_width summary_width=
  879.   alias set_summary_indent summary_indent=
  880.  
  881.   # Version
  882.   attr_writer :version
  883.   # Release code
  884.   attr_writer :release
  885.  
  886.   #
  887.   # Version
  888.   #
  889.   def version
  890.     @version || (defined?(::Version) && ::Version)
  891.   end
  892.  
  893.   #
  894.   # Release code
  895.   #
  896.   def release
  897.     @release || (defined?(::Release) && ::Release) || (defined?(::RELEASE) && ::RELEASE)
  898.   end
  899.  
  900.   #
  901.   # Returns version string from program_name, version and release.
  902.   #
  903.   def ver
  904.     if v = version
  905.       str = "#{program_name} #{[v].join('.')}"
  906.       str << " (#{v})" if v = release
  907.       str
  908.     end
  909.   end
  910.  
  911.   def warn(mesg = $!)
  912.     super("#{program_name}: #{mesg}")
  913.   end
  914.  
  915.   def abort(mesg = $!)
  916.     super("#{program_name}: #{mesg}")
  917.   end
  918.  
  919.   #
  920.   # Subject of #on / #on_head, #accept / #reject
  921.   #
  922.   def top
  923.     @stack[-1]
  924.   end
  925.  
  926.   #
  927.   # Subject of #on_tail.
  928.   #
  929.   def base
  930.     @stack[1]
  931.   end
  932.  
  933.   #
  934.   # Pushes a new List.
  935.   #
  936.   def new
  937.     @stack.push(List.new)
  938.     if block_given?
  939.       yield self
  940.     else
  941.       self
  942.     end
  943.   end
  944.  
  945.   #
  946.   # Removes the last List.
  947.   #
  948.   def remove
  949.     @stack.pop
  950.   end
  951.  
  952.   #
  953.   # Puts option summary into +to+ and returns +to+. Yields each line if
  954.   # a block is given.
  955.   #
  956.   # +to+:: Output destination, which must have method <<. Defaults to [].
  957.   # +width+:: Width of left side, defaults to @summary_width.
  958.   # +max+:: Maximum length allowed for left side, defaults to +width+ - 1.
  959.   # +indent+:: Indentation, defaults to @summary_indent.
  960.   #
  961.   def summarize(to = [], width = @summary_width, max = width - 1, indent = @summary_indent, &blk)
  962.     visit(:summarize, {}, {}, width, max, indent, &(blk || proc {|l| to << l + $/}))
  963.     to
  964.   end
  965.  
  966.   #
  967.   # Returns option summary string.
  968.   #
  969.   def help; summarize(banner.to_s.sub(/\n?\z/, "\n")) end
  970.   alias to_s help
  971.  
  972.   #
  973.   # Returns option summary list.
  974.   #
  975.   def to_a; summarize(banner.to_a.dup) end
  976.  
  977.   #
  978.   # Checks if an argument is given twice, in which case an ArgumentError is
  979.   # raised. Called from OptionParser#switch only.
  980.   #
  981.   # +obj+:: New argument.
  982.   # +prv+:: Previously specified argument.
  983.   # +msg+:: Exception message.
  984.   #
  985.   def notwice(obj, prv, msg)
  986.     unless !prv or prv == obj
  987.       begin
  988.         raise ArgumentError, "argument #{msg} given twice: #{obj}"
  989.       rescue
  990.         $@[0, 2] = nil
  991.         raise
  992.       end
  993.     end
  994.     obj
  995.   end
  996.   private :notwice
  997.  
  998.   #
  999.   # Creates an OptionParser::Switch from the parameters. The parsed argument
  1000.   # value is passed to the given block, where it can be processed.
  1001.   #
  1002.   # See at the beginning of OptionParser for some full examples.
  1003.   #
  1004.   # +opts+ can include the following elements:
  1005.   #
  1006.   # [Argument style:]
  1007.   #   One of the following:
  1008.   #     :NONE, :REQUIRED, :OPTIONAL
  1009.   #
  1010.   # [Argument pattern:]
  1011.   #   Acceptable option argument format, must be pre-defined with
  1012.   #   OptionParser.accept or OptionParser#accept, or Regexp. This can appear
  1013.   #   once or assigned as String if not present, otherwise causes an
  1014.   #   ArgumentError. Examples:
  1015.   #     Float, Time, Array
  1016.   #
  1017.   # [Possible argument values:]
  1018.   #   Hash or Array.
  1019.   #     [:text, :binary, :auto]
  1020.   #     %w[iso-2022-jp shift_jis euc-jp utf8 binary]
  1021.   #     { "jis" => "iso-2022-jp", "sjis" => "shift_jis" }
  1022.   #
  1023.   # [Long style switch:]
  1024.   #   Specifies a long style switch which takes a mandatory, optional or no
  1025.   #   argument. It's a string of the following form:
  1026.   #     "--switch=MANDATORY" or "--switch MANDATORY"
  1027.   #     "--switch[=OPTIONAL]"
  1028.   #     "--switch"
  1029.   #
  1030.   # [Short style switch:]
  1031.   #   Specifies short style switch which takes a mandatory, optional or no
  1032.   #   argument. It's a string of the following form:
  1033.   #     "-xMANDATORY"
  1034.   #     "-x[OPTIONAL]"
  1035.   #     "-x"
  1036.   #   There is also a special form which matches character range (not full
  1037.   #   set of regular expression):
  1038.   #     "-[a-z]MANDATORY"
  1039.   #     "-[a-z][OPTIONAL]" 
  1040.   #     "-[a-z]"
  1041.   #
  1042.   # [Argument style and description:]
  1043.   #   Instead of specifying mandatory or optional arguments directly in the
  1044.   #   switch parameter, this separate parameter can be used.
  1045.   #     "=MANDATORY"
  1046.   #     "=[OPTIONAL]"
  1047.   #
  1048.   # [Description:]
  1049.   #   Description string for the option.
  1050.   #     "Run verbosely"
  1051.   # 
  1052.   # [Handler:]
  1053.   #   Handler for the parsed argument value. Either give a block or pass a
  1054.   #   Proc or Method as an argument.
  1055.   #
  1056.   def make_switch(opts, block = nil)
  1057.     short, long, nolong, style, pattern, conv, not_pattern, not_conv, not_style = [], [], []
  1058.     ldesc, sdesc, desc, arg = [], [], []
  1059.     default_style = Switch::NoArgument
  1060.     default_pattern = nil
  1061.     klass = nil
  1062.     o = nil
  1063.     n, q, a = nil
  1064.  
  1065.     opts.each do |o|
  1066.       # argument class
  1067.       next if search(:atype, o) do |pat, c|
  1068.         klass = notwice(o, klass, 'type')
  1069.         if not_style and not_style != Switch::NoArgument
  1070.           not_pattern, not_conv = pat, c
  1071.         else
  1072.           default_pattern, conv = pat, c
  1073.         end
  1074.       end
  1075.  
  1076.       # directly specified pattern(any object possible to match)
  1077.       if !(String === o) and o.respond_to?(:match)
  1078.         pattern = notwice(o, pattern, 'pattern')
  1079.         conv = pattern.method(:convert).to_proc if pattern.respond_to?(:convert)
  1080.         next
  1081.       end
  1082.  
  1083.       # anything others
  1084.       case o
  1085.       when Proc, Method
  1086.         block = notwice(o, block, 'block')
  1087.       when Array, Hash
  1088.         case pattern
  1089.         when CompletingHash
  1090.         when nil
  1091.           pattern = CompletingHash.new
  1092.           conv = pattern.method(:convert).to_proc if pattern.respond_to?(:convert)
  1093.         else
  1094.           raise ArgumentError, "argument pattern given twice"
  1095.         end
  1096.         o.each {|(o, *v)| pattern[o] = v.fetch(0) {o}}
  1097.       when Module
  1098.         raise ArgumentError, "unsupported argument type: #{o}"
  1099.       when *ArgumentStyle.keys
  1100.         style = notwice(ArgumentStyle[o], style, 'style')
  1101.       when /^--no-([^\[\]=\s]*)(.+)?/
  1102.         q, a = $1, $2
  1103.         o = notwice(a ? Object : TrueClass, klass, 'type')
  1104.         not_pattern, not_conv = search(:atype, o) unless not_style
  1105.         not_style = (not_style || default_style).guess(arg = a) if a
  1106.         default_style = Switch::NoArgument
  1107.         default_pattern, conv = search(:atype, FalseClass) unless default_pattern
  1108.         ldesc << "--no-#{q}"
  1109.         long << 'no-' + (q = q.downcase)
  1110.         nolong << q
  1111.       when /^--\[no-\]([^\[\]=\s]*)(.+)?/
  1112.         q, a = $1, $2
  1113.         o = notwice(a ? Object : TrueClass, klass, 'type')
  1114.         if a
  1115.           default_style = default_style.guess(arg = a)
  1116.           default_pattern, conv = search(:atype, o) unless default_pattern
  1117.         end
  1118.         ldesc << "--[no-]#{q}"
  1119.         long << (o = q.downcase)
  1120.         not_pattern, not_conv = search(:atype, FalseClass) unless not_style
  1121.         not_style = Switch::NoArgument
  1122.         nolong << 'no-' + o
  1123.       when /^--([^\[\]=\s]*)(.+)?/
  1124.         q, a = $1, $2
  1125.         if a
  1126.           o = notwice(NilClass, klass, 'type')
  1127.           default_style = default_style.guess(arg = a)
  1128.           default_pattern, conv = search(:atype, o) unless default_pattern
  1129.         end
  1130.         ldesc << "--#{q}"
  1131.         long << (o = q.downcase)
  1132.       when /^-(\[\^?\]?(?:[^\\\]]|\\.)*\])(.+)?/
  1133.         q, a = $1, $2
  1134.         o = notwice(Object, klass, 'type')
  1135.         if a
  1136.           default_style = default_style.guess(arg = a)
  1137.           default_pattern, conv = search(:atype, o) unless default_pattern
  1138.         end
  1139.         sdesc << "-#{q}"
  1140.         short << Regexp.new(q)
  1141.       when /^-(.)(.+)?/
  1142.         q, a = $1, $2
  1143.         if a
  1144.           o = notwice(NilClass, klass, 'type')
  1145.           default_style = default_style.guess(arg = a)
  1146.           default_pattern, conv = search(:atype, o) unless default_pattern
  1147.         end
  1148.         sdesc << "-#{q}"
  1149.         short << q
  1150.       when /^=/
  1151.         style = notwice(default_style.guess(arg = o), style, 'style')
  1152.         default_pattern, conv = search(:atype, Object) unless default_pattern
  1153.       else
  1154.         desc.push(o)
  1155.       end
  1156.     end
  1157.  
  1158.     default_pattern, conv = search(:atype, default_style.pattern) unless default_pattern
  1159.     if !(short.empty? and long.empty?)
  1160.       s = (style || default_style).new(pattern || default_pattern,
  1161.                                        conv, sdesc, ldesc, arg, desc, block)
  1162.     elsif !block
  1163.       raise ArgumentError, "no switch given" if style or pattern
  1164.       s = desc
  1165.     else
  1166.       short << pattern
  1167.       s = (style || default_style).new(pattern,
  1168.                                        conv, nil, nil, arg, desc, block)
  1169.     end
  1170.     return s, short, long,
  1171.       (not_style.new(not_pattern, not_conv, sdesc, ldesc, nil, desc, block) if not_style),
  1172.       nolong
  1173.   end
  1174.  
  1175.   def define(*opts, &block)
  1176.     top.append(*(sw = make_switch(opts, block)))
  1177.     sw[0]
  1178.   end
  1179.  
  1180.   #
  1181.   # Add option switch and handler. See #make_switch for an explanation of
  1182.   # parameters.
  1183.   #
  1184.   def on(*opts, &block)
  1185.     define(*opts, &block)
  1186.     self
  1187.   end
  1188.   alias def_option define
  1189.  
  1190.   def define_head(*opts, &block)
  1191.     top.prepend(*(sw = make_switch(opts, block)))
  1192.     sw[0]
  1193.   end
  1194.  
  1195.   #
  1196.   # Add option switch like with #on, but at head of summary.
  1197.   #
  1198.   def on_head(*opts, &block)
  1199.     define_head(*opts, &block)
  1200.     self
  1201.   end
  1202.   alias def_head_option define_head
  1203.  
  1204.   def define_tail(*opts, &block)
  1205.     base.append(*(sw = make_switch(opts, block)))
  1206.     sw[0]
  1207.   end
  1208.  
  1209.   #
  1210.   # Add option switch like with #on, but at tail of summary.
  1211.   #
  1212.   def on_tail(*opts, &block)
  1213.     define_tail(*opts, &block)
  1214.     self
  1215.   end
  1216.   alias def_tail_option define_tail
  1217.  
  1218.   #
  1219.   # Add separator in summary.
  1220.   #
  1221.   def separator(string)
  1222.     top.append(string, nil, nil)
  1223.   end
  1224.  
  1225.   #
  1226.   # Parses command line arguments +argv+ in order. When a block is given,
  1227.   # each non-option argument is yielded.
  1228.   #
  1229.   # Returns the rest of +argv+ left unparsed.
  1230.   #
  1231.   def order(*argv, &block)
  1232.     argv = argv[0].dup if argv.size == 1 and Array === argv[0]
  1233.     order!(argv, &block)
  1234.   end
  1235.  
  1236.   #
  1237.   # Same as #order, but removes switches destructively.
  1238.   #
  1239.   def order!(argv = default_argv, &nonopt)
  1240.     parse_in_order(argv, &nonopt)
  1241.   end
  1242.  
  1243.   def parse_in_order(argv = default_argv, setter = nil, &nonopt)  # :nodoc:
  1244.     opt, arg, sw, val, rest = nil
  1245.     nonopt ||= proc {|arg| throw :terminate, arg}
  1246.     argv.unshift(arg) if arg = catch(:terminate) {
  1247.       while arg = argv.shift
  1248.         case arg
  1249.         # long option
  1250.         when /\A--([^=]*)(?:=(.*))?/nm
  1251.           opt, rest = $1, $2
  1252.           begin
  1253.             sw, = complete(:long, opt, true)
  1254.           rescue ParseError
  1255.             raise $!.set_option(arg, true)
  1256.           end
  1257.           begin
  1258.             opt, cb, val = sw.parse(rest, argv) {|*exc| raise(*exc)}
  1259.             val = cb.call(val) if cb
  1260.             setter.call(sw.switch_name, val) if setter
  1261.           rescue ParseError
  1262.             raise $!.set_option(arg, rest)
  1263.           end
  1264.  
  1265.         # short option
  1266.         when /\A-(.)((=).*|.+)?/nm
  1267.           opt, has_arg, eq, val, rest = $1, $3, $3, $2, $2
  1268.           begin
  1269.             sw, = search(:short, opt)
  1270.             unless sw
  1271.               begin
  1272.                 sw, = complete(:short, opt)
  1273.                 # short option matched.
  1274.                 val = arg.sub(/\A-/, '')
  1275.                 has_arg = true
  1276.               rescue InvalidOption
  1277.                 # if no short options match, try completion with long
  1278.                 # options.
  1279.                 sw, = complete(:long, opt)
  1280.                 eq ||= !rest
  1281.               end
  1282.             end
  1283.           rescue ParseError
  1284.             raise $!.set_option(arg, true)
  1285.           end
  1286.           begin
  1287.             opt, cb, val = sw.parse(val, argv) {|*exc| raise(*exc) if eq}
  1288.             raise InvalidOption, arg if has_arg and !eq and arg == "-#{opt}"
  1289.             argv.unshift(opt) if opt and (opt = opt.sub(/\A-*/, '-')) != '-'
  1290.             val = cb.call(val) if cb
  1291.             setter.call(sw.switch_name, val) if setter
  1292.           rescue ParseError
  1293.             raise $!.set_option(arg, arg.length > 2)
  1294.           end
  1295.  
  1296.         # non-option argument
  1297.         else
  1298.           catch(:prune) do
  1299.             visit(:each_option) do |sw|
  1300.               sw.block.call(arg) if Switch === sw and sw.match_nonswitch?(arg)
  1301.             end
  1302.             nonopt.call(arg)
  1303.           end
  1304.         end
  1305.       end
  1306.  
  1307.       nil
  1308.     }
  1309.  
  1310.     visit(:search, :short, nil) {|sw| sw.block.call(*argv) if !sw.pattern}
  1311.  
  1312.     argv
  1313.   end
  1314.   private :parse_in_order
  1315.  
  1316.   #
  1317.   # Parses command line arguments +argv+ in permutation mode and returns
  1318.   # list of non-option arguments.
  1319.   #
  1320.   def permute(*argv)
  1321.     argv = argv[0].dup if argv.size == 1 and Array === argv[0]
  1322.     permute!(argv)
  1323.   end
  1324.  
  1325.   #
  1326.   # Same as #permute, but removes switches destructively.
  1327.   #
  1328.   def permute!(argv = default_argv)
  1329.     nonopts = []
  1330.     arg = nil
  1331.     order!(argv) {|arg| nonopts << arg}
  1332.     argv[0, 0] = nonopts
  1333.     argv
  1334.   end
  1335.  
  1336.   #
  1337.   # Parses command line arguments +argv+ in order when environment variable
  1338.   # POSIXLY_CORRECT is set, and in permutation mode otherwise.
  1339.   #
  1340.   def parse(*argv)
  1341.     argv = argv[0].dup if argv.size == 1 and Array === argv[0]
  1342.     parse!(argv)
  1343.   end
  1344.  
  1345.   #
  1346.   # Same as #parse, but removes switches destructively.
  1347.   #
  1348.   def parse!(argv = default_argv)
  1349.     if ENV.include?('POSIXLY_CORRECT')
  1350.       order!(argv)
  1351.     else
  1352.       permute!(argv)
  1353.     end
  1354.   end
  1355.  
  1356.   #
  1357.   # Wrapper method for getopts.rb.
  1358.   #
  1359.   #   params = ARGV.getopts("ab:", "foo", "bar:")
  1360.   #   # params[:a] = true   # -a
  1361.   #   # params[:b] = "1"    # -b1
  1362.   #   # params[:foo] = "1"  # --foo
  1363.   #   # params[:bar] = "x"  # --bar x
  1364.   #
  1365.   def getopts(*args)
  1366.     argv = Array === args.first ? args.shift : default_argv
  1367.     single_options, *long_options = *args
  1368.  
  1369.     result = {}
  1370.  
  1371.     single_options.scan(/(.)(:)?/) do |opt, val|
  1372.       if val
  1373.         result[opt] = nil
  1374.         define("-#{opt} VAL")
  1375.       else
  1376.         result[opt] = false
  1377.         define("-#{opt}")
  1378.       end
  1379.     end if single_options
  1380.  
  1381.     long_options.each do |arg|
  1382.       opt, val = arg.split(':', 2)
  1383.       if val
  1384.         result[opt] = val.empty? ? nil : val
  1385.         define("--#{opt} VAL")
  1386.       else
  1387.         result[opt] = false
  1388.         define("--#{opt}")
  1389.       end
  1390.     end
  1391.  
  1392.     parse_in_order(argv, result.method(:[]=))
  1393.     result
  1394.   end
  1395.  
  1396.   #
  1397.   # See #getopts.
  1398.   #
  1399.   def self.getopts(*args)
  1400.     new.getopts(*args)
  1401.   end
  1402.  
  1403.   #
  1404.   # Traverses @stack, sending each element method +id+ with +args+ and
  1405.   # +block+.
  1406.   #
  1407.   def visit(id, *args, &block)
  1408.     el = nil
  1409.     @stack.reverse_each do |el|
  1410.       el.send(id, *args, &block)
  1411.     end
  1412.     nil
  1413.   end
  1414.   private :visit
  1415.  
  1416.   #
  1417.   # Searches +key+ in @stack for +id+ hash and returns or yields the result.
  1418.   #
  1419.   def search(id, key)
  1420.     block_given = block_given?
  1421.     visit(:search, id, key) do |k|
  1422.       return block_given ? yield(k) : k
  1423.     end
  1424.   end
  1425.   private :search
  1426.  
  1427.   #
  1428.   # Completes shortened long style option switch and returns pair of
  1429.   # canonical switch and switch descriptor OptionParser::Switch.
  1430.   #
  1431.   # +id+::    Searching table.
  1432.   # +opt+::   Searching key.
  1433.   # +icase+:: Search case insensitive if true.
  1434.   # +pat+::   Optional pattern for completion.
  1435.   #
  1436.   def complete(typ, opt, icase = false, *pat)
  1437.     if pat.empty?
  1438.       search(typ, opt) {|sw| return [sw, opt]} # exact match or...
  1439.     end
  1440.     raise AmbiguousOption, catch(:ambiguous) {
  1441.       visit(:complete, typ, opt, icase, *pat) {|opt, *sw| return sw}
  1442.       raise InvalidOption, opt
  1443.     }
  1444.   end
  1445.   private :complete
  1446.  
  1447.   #
  1448.   # Loads options from file names as +filename+. Does nothing when the file
  1449.   # is not present. Returns whether successfully loaded.
  1450.   #
  1451.   # +filename+ defaults to basename of the program without suffix in a
  1452.   # directory ~/.options.
  1453.   #
  1454.   def load(filename = nil)
  1455.     begin
  1456.       filename ||= File.expand_path(File.basename($0, '.*'), '~/.options')
  1457.     rescue
  1458.       return false
  1459.     end
  1460.     begin
  1461.       parse(*IO.readlines(filename).each {|s| s.chomp!})
  1462.       true
  1463.     rescue Errno::ENOENT, Errno::ENOTDIR
  1464.       false
  1465.     end
  1466.   end
  1467.  
  1468.   #
  1469.   # Parses environment variable +env+ or its uppercase with splitting like a
  1470.   # shell.
  1471.   #
  1472.   # +env+ defaults to the basename of the program.
  1473.   #
  1474.   def environment(env = File.basename($0, '.*'))
  1475.     env = ENV[env] || ENV[env.upcase] or return
  1476.     require 'shellwords'
  1477.     parse(*Shellwords.shellwords(env))
  1478.   end
  1479.  
  1480.   #
  1481.   # Acceptable argument classes
  1482.   #
  1483.  
  1484.   #
  1485.   # Any string and no conversion. This is fall-back.
  1486.   #
  1487.   accept(Object) {|s,|s or s.nil?}
  1488.  
  1489.   accept(NilClass) {|s,|s}
  1490.  
  1491.   #
  1492.   # Any non-empty string, and no conversion.
  1493.   #
  1494.   accept(String, /.+/nm) {|s,*|s}
  1495.  
  1496.   #
  1497.   # Ruby/C-like integer, octal for 0-7 sequence, binary for 0b, hexadecimal
  1498.   # for 0x, and decimal for others; with optional sign prefix. Converts to
  1499.   # Integer.
  1500.   #
  1501.   decimal = '\d+(?:_\d+)*'
  1502.   binary = 'b[01]+(?:_[01]+)*'
  1503.   hex = 'x[\da-f]+(?:_[\da-f]+)*'
  1504.   octal = "0(?:[0-7]*(?:_[0-7]+)*|#{binary}|#{hex})"
  1505.   integer = "#{octal}|#{decimal}"
  1506.   accept(Integer, %r"\A[-+]?(?:#{integer})"io) {|s,| Integer(s) if s}
  1507.  
  1508.   #
  1509.   # Float number format, and converts to Float.
  1510.   #
  1511.   float = "(?:#{decimal}(?:\\.(?:#{decimal})?)?|\\.#{decimal})(?:E[-+]?#{decimal})?"
  1512.   floatpat = %r"\A[-+]?#{float}"io
  1513.   accept(Float, floatpat) {|s,| s.to_f if s}
  1514.  
  1515.   #
  1516.   # Generic numeric format, converts to Integer for integer format, Float
  1517.   # for float format.
  1518.   #
  1519.   accept(Numeric, %r"\A[-+]?(?:#{octal}|#{float})"io) {|s,| eval(s) if s}
  1520.  
  1521.   #
  1522.   # Decimal integer format, to be converted to Integer.
  1523.   #
  1524.   DecimalInteger = /\A[-+]?#{decimal}/io
  1525.   accept(DecimalInteger) {|s,| s.to_i if s}
  1526.  
  1527.   #
  1528.   # Ruby/C like octal/hexadecimal/binary integer format, to be converted to
  1529.   # Integer.
  1530.   #
  1531.   OctalInteger = /\A[-+]?(?:[0-7]+(?:_[0-7]+)*|0(?:#{binary}|#{hex}))/io
  1532.   accept(OctalInteger) {|s,| s.oct if s}
  1533.  
  1534.   #
  1535.   # Decimal integer/float number format, to be converted to Integer for
  1536.   # integer format, Float for float format.
  1537.   #
  1538.   DecimalNumeric = floatpat     # decimal integer is allowed as float also.
  1539.   accept(DecimalNumeric) {|s,| eval(s) if s}
  1540.  
  1541.   #
  1542.   # Boolean switch, which means whether it is present or not, whether it is
  1543.   # absent or not with prefix no-, or it takes an argument
  1544.   # yes/no/true/false/+/-.
  1545.   #
  1546.   yesno = CompletingHash.new
  1547.   %w[- no false].each {|el| yesno[el] = false}
  1548.   %w[+ yes true].each {|el| yesno[el] = true}
  1549.   yesno['nil'] = false          # shoud be nil?
  1550.   accept(TrueClass, yesno) {|arg, val| val == nil or val}
  1551.   #
  1552.   # Similar to TrueClass, but defaults to false.
  1553.   #
  1554.   accept(FalseClass, yesno) {|arg, val| val != nil and val}
  1555.  
  1556.   #
  1557.   # List of strings separated by ",".
  1558.   #
  1559.   accept(Array) do |s,|
  1560.     if s
  1561.       s = s.split(',').collect {|s| s unless s.empty?}
  1562.     end
  1563.     s
  1564.   end
  1565.  
  1566.   #
  1567.   # Regular expression with options.
  1568.   #
  1569.   accept(Regexp, %r"\A/((?:\\.|[^\\])*)/([[:alpha:]]+)?\z|.*") do |all, s, o|
  1570.     f = 0
  1571.     if o
  1572.       f |= Regexp::IGNORECASE if /i/ =~ o
  1573.       f |= Regexp::MULTILINE if /m/ =~ o
  1574.       f |= Regexp::EXTENDED if /x/ =~ o
  1575.       k = o.delete("^imx")
  1576.     end
  1577.     Regexp.new(s || all, f, k)
  1578.   end
  1579.  
  1580.   #
  1581.   # Exceptions
  1582.   #
  1583.  
  1584.   #
  1585.   # Base class of exceptions from OptionParser.
  1586.   #
  1587.   class ParseError < RuntimeError
  1588.     # Reason which caused the error.
  1589.     Reason = 'parse error'.freeze
  1590.  
  1591.     def initialize(*args)
  1592.       @args = args
  1593.       @reason = nil
  1594.     end
  1595.  
  1596.     attr_reader :args
  1597.     attr_writer :reason
  1598.  
  1599.     #
  1600.     # Pushes back erred argument(s) to +argv+.
  1601.     #
  1602.     def recover(argv)
  1603.       argv[0, 0] = @args
  1604.       argv
  1605.     end
  1606.  
  1607.     def set_option(opt, eq)
  1608.       if eq
  1609.         @args[0] = opt
  1610.       else
  1611.         @args.unshift(opt)
  1612.       end
  1613.       self
  1614.     end
  1615.  
  1616.     #
  1617.     # Returns error reason. Override this for I18N.
  1618.     #
  1619.     def reason
  1620.       @reason || self.class::Reason
  1621.     end
  1622.  
  1623.     def inspect
  1624.       "#<#{self.class.to_s}: #{args.join(' ')}>"
  1625.     end
  1626.  
  1627.     #
  1628.     # Default stringizing method to emit standard error message.
  1629.     #
  1630.     def message
  1631.       reason + ': ' + args.join(' ')
  1632.     end
  1633.  
  1634.     alias to_s message
  1635.   end
  1636.  
  1637.   #
  1638.   # Raises when ambiguously completable string is encountered.
  1639.   #
  1640.   class AmbiguousOption < ParseError
  1641.     const_set(:Reason, 'ambiguous option'.freeze)
  1642.   end
  1643.  
  1644.   #
  1645.   # Raises when there is an argument for a switch which takes no argument.
  1646.   #
  1647.   class NeedlessArgument < ParseError
  1648.     const_set(:Reason, 'needless argument'.freeze)
  1649.   end
  1650.  
  1651.   #
  1652.   # Raises when a switch with mandatory argument has no argument.
  1653.   #
  1654.   class MissingArgument < ParseError
  1655.     const_set(:Reason, 'missing argument'.freeze)
  1656.   end
  1657.  
  1658.   #
  1659.   # Raises when switch is undefined.
  1660.   #
  1661.   class InvalidOption < ParseError
  1662.     const_set(:Reason, 'invalid option'.freeze)
  1663.   end
  1664.  
  1665.   #
  1666.   # Raises when the given argument does not match required format.
  1667.   #
  1668.   class InvalidArgument < ParseError
  1669.     const_set(:Reason, 'invalid argument'.freeze)
  1670.   end
  1671.  
  1672.   #
  1673.   # Raises when the given argument word can't be completed uniquely.
  1674.   #
  1675.   class AmbiguousArgument < InvalidArgument
  1676.     const_set(:Reason, 'ambiguous argument'.freeze)
  1677.   end
  1678.  
  1679.   #
  1680.   # Miscellaneous
  1681.   #
  1682.  
  1683.   #
  1684.   # Extends command line arguments array (ARGV) to parse itself.
  1685.   #
  1686.   module Arguable
  1687.  
  1688.     #
  1689.     # Sets OptionParser object, when +opt+ is +false+ or +nil+, methods
  1690.     # OptionParser::Arguable#options and OptionParser::Arguable#options= are
  1691.     # undefined. Thus, there is no ways to access the OptionParser object
  1692.     # via the receiver object.
  1693.     #
  1694.     def options=(opt)
  1695.       unless @optparse = opt
  1696.         class << self
  1697.           undef_method(:options)
  1698.           undef_method(:options=)
  1699.         end
  1700.       end
  1701.     end
  1702.  
  1703.     #
  1704.     # Actual OptionParser object, automatically created if nonexistent.
  1705.     #
  1706.     # If called with a block, yields the OptionParser object and returns the
  1707.     # result of the block. If an OptionParser::ParseError exception occurs
  1708.     # in the block, it is rescued, a error message printed to STDERR and
  1709.     # +nil+ returned.
  1710.     #
  1711.     def options
  1712.       @optparse ||= OptionParser.new
  1713.       @optparse.default_argv = self
  1714.       block_given? or return @optparse
  1715.       begin
  1716.         yield @optparse
  1717.       rescue ParseError
  1718.         @optparse.warn $!
  1719.         nil
  1720.       end
  1721.     end
  1722.  
  1723.     #
  1724.     # Parses +self+ destructively in order and returns +self+ containing the
  1725.     # rest arguments left unparsed.
  1726.     #
  1727.     def order!(&blk) options.order!(self, &blk) end
  1728.  
  1729.     #
  1730.     # Parses +self+ destructively in permutation mode and returns +self+
  1731.     # containing the rest arguments left unparsed.
  1732.     #
  1733.     def permute!() options.permute!(self) end
  1734.  
  1735.     #
  1736.     # Parses +self+ destructively and returns +self+ containing the
  1737.     # rest arguments left unparsed.
  1738.     #
  1739.     def parse!() options.parse!(self) end
  1740.  
  1741.     #
  1742.     # Substitution of getopts is possible as follows. Also see
  1743.     # OptionParser#getopts.
  1744.     #
  1745.     #   def getopts(*args)
  1746.     #     ($OPT = ARGV.getopts(*args)).each do |opt, val|
  1747.     #       eval "$OPT_#{opt.gsub(/[^A-Za-z0-9_]/, '_')} = val"
  1748.     #     end
  1749.     #   rescue OptionParser::ParseError
  1750.     #   end
  1751.     #
  1752.     def getopts(*args)
  1753.       options.getopts(self, *args)
  1754.     end
  1755.  
  1756.     #
  1757.     # Initializes instance variable.
  1758.     #
  1759.     def self.extend_object(obj)
  1760.       super
  1761.       obj.instance_eval {@optparse = nil}
  1762.     end
  1763.     def initialize(*args)
  1764.       super
  1765.       @optparse = nil
  1766.     end
  1767.   end
  1768.  
  1769.   #
  1770.   # Acceptable argument classes. Now contains DecimalInteger, OctalInteger
  1771.   # and DecimalNumeric. See Acceptable argument classes (in source code).
  1772.   #
  1773.   module Acceptables
  1774.     const_set(:DecimalInteger, OptionParser::DecimalInteger)
  1775.     const_set(:OctalInteger, OptionParser::OctalInteger)
  1776.     const_set(:DecimalNumeric, OptionParser::DecimalNumeric)
  1777.   end
  1778. end
  1779.  
  1780. # ARGV is arguable by OptionParser
  1781. ARGV.extend(OptionParser::Arguable)
  1782.  
  1783. if $0 == __FILE__
  1784.   Version = OptionParser::Version
  1785.   ARGV.options {|q|
  1786.     q.parse!.empty? or puts "what's #{ARGV.join(' ')}?"
  1787.   } or abort(ARGV.options.to_s)
  1788. end
  1789.